/*************************************************
* Title：TinyToolKit
* Author：Opportunity 
* Describe：存储游戏运行中的数据
 * 任意类型的数据以树状结构进行存储
* CreateTime：2021-03-01 13:55:01
* Version：1.0
* Modify Recorder：
*************************************************/

namespace TinyToolKit.DataTree
{
    public class TDataNodeManager : ManagerBase
    {
        private const string RootName = "Root";
        private DataNode _root;

        public DataNode Root => _root;

        public override void Init()
        {
            _root = new DataNode(RootName);
        }

        public override void UpdateManager()
        {
            
        }

        public override void Shutdown()
        {
            Clear();
            _root = null;
        }

        /// <summary>
        /// 根据路径获取对应结点
        /// </summary>
        /// <param name="path">结点的路径</param>
        /// <returns>如果路径存在，返回对应的结点，否则返回空</returns>
        public DataNode GetNode(string path)
        {
            DataNode curNode = _root;
            string[] paths = GetSplitPath(path);

            for (int i = 0; i < paths.Length; i++)
            {
                curNode = curNode.GetChildNode(paths[i]);
                if (curNode == null) return null;
            }

            return curNode;
        }
        
        /// <summary>
        /// 根据路径移除结点，同时移除其所有的子结点
        /// </summary>
        /// <param name="path">结点路径</param>
        public void RemoveNode(string path)
        {
            DataNode node = GetNode(path);
            if (node == null) return;
            
            DataNode parent = node.Parent;
            parent?.RemoveChildNode(node.Name);
        }

        /// <summary>
        /// 根据路径返回结点的数据
        /// </summary>
        /// <param name="path">结点的路径</param>
        /// <typeparam name="T">数据的类型</typeparam>
        /// <returns>返回对应类型的数据</returns>
        public T GetData<T>(string path) where T : TinyData
        {
            DataNode node = GetNode(path);
            return node?.GetData<T>();
        }
        
        /// <summary>
        /// 根据路径设置结点的数据，如果该结点不存在则创建
        /// </summary>
        /// <param name="path">结点的路径</param>
        /// <param name="data">数据类型的实例</param>
        /// <typeparam name="T">数据类型</typeparam>
        public void SetData<T>(string path,T data) where T : TinyData
        {
            DataNode curNode = _root;
            string[] paths = GetSplitPath(path);

            for (int i = 0; i < paths.Length; i++)
            {
                if (curNode.HasChildNode(paths[i]) == false)
                    curNode.AddChildNode(paths[i],null);

                curNode = curNode.GetChildNode(paths[i]);
            }
            curNode.SetData(data);
        }

        /// <summary>
        /// 清除所有结点的数据
        /// </summary>
        public void Clear()
        {
            _root.Clear();
        }

        private string[] GetSplitPath(string path)
        {
            if (path.IsNullOrEmpty()) return null;

            return path.Split('.');
        }
    }
}
